#include "Gun.h"

Gun::Gun(): mBulletTimer(0){}

Gun::~Gun(){}

//-- Return the guns currently active bullets
std::vector<Bullet> Gun::GetBullets()
{
	return mCurrentBullets;
}

//-- Update all bullets fired by the gun
void Gun::UpdateBullets(EnemyMgr* enemyManager, Player* player)
{
	//-- Get the current enemy vector
	std::vector<Enemy>& enemies = enemyManager->GetEnemies();

	//-- Bullet timer is used to control the fire rate
	mBulletTimer--;
	
	//-- Iterate through all bullets
	for ( std::vector<Bullet>::iterator mBulletIterator = mCurrentBullets.begin(); mBulletIterator != mCurrentBullets.end();)
	{ 
	
		//-- Get the bullet angle
		abfw::Matrix44 bulletAngle;
		bulletAngle.RotationZ(mBulletIterator->GetAngle());

		//-- Move the bullet
		mBulletIterator->Move();

		//-- Increment the time the bullet has been alive
		mBulletIterator->life++;

		//-- Set the final transform
		mBulletIterator->SetTransform(*mBulletIterator->GetLocalTransform() *
										//-- Direction to fire
										bulletAngle *
										//-- Scale
										 mBulletIterator->GetLocalScale() *
										 //-- Relative marker position
										 mBulletIterator->GetMarkerInstance());
		
	
		//-- Calculate distance travelled
		abfw::Vector3 distance;
		distance = mBulletIterator->GetLocalTransform()->GetTranslation() -  mBulletIterator->GetMarkerInstance().GetTranslation();
		
		//-- Set bullet to delete if its travelled a certain distance
		if (mBulletIterator->life > 50)
		{
			mBulletIterator->trash = true;
		}

		for (int i = 0; i < enemies.size(); i++)
		{
			if (enemies[i].IsDead() == false)
			{
				//-- Check for collision between bullet and enemy
				if (CollisionDetection::AABB(mBulletIterator->GetMeshInstance(), enemies[i].GetMeshInstance()))
					{
						//-- Set bullet to delete if it comes into contact with enemy
						mBulletIterator->trash = true;
						
						//-- Decrease the enemy health
						enemies[i].DecreaseHealth(enemyManager->GetEnemyDamage());

						//-- Set the enemy to dead if its health is below or equal to 0
						if (enemies[i].GetHealth() <= 0)
						{
							if (player->GetPowerLevel() < 100)
							player->SetPowerLevel(player->GetCurrentPowerUpAmount());
							enemies[i].SetDead(true);
						}
					}
			
			
			}
		}

		//-- If bullet needs to be deleted
		if ( mBulletIterator->trash == true )
		{
			//-- Remove from iterator
			mBulletIterator = mCurrentBullets.erase(mBulletIterator);
		}
		else
		{
			//-- Continue loop
			++mBulletIterator;
		}
	}
}


//-- Add a new bullet, initialise it then set its direction then add it to the bullet vector
void Gun::Fire(float rotationAngle, abfw::Mesh* mesh, abfw::Matrix44 gunPosition )
{
	//-- If the gun can fire
	if (mBulletTimer <= 0)
	{
		//-- Create a bullet
		Bullet bullet;
		bullet.Init(mesh);
		bullet.SetLocalScale(abfw::Vector3(0.003f, 0.003f, 0.003f));

		//-- Sets the marker transform at time of firing
		mMarkerTransformInstance = gunPosition;
		bullet.SetMarkerInstance(gunPosition);

		bullet.SetRotationAngle(rotationAngle);
		bullet.SetVelocity(abfw::Vector3(2.5f, 0.0f, 0.0f));

		//-- Add bullet to current vector
		mCurrentBullets.push_back(bullet);
		//-- Reset bullet timer
		mBulletTimer = 10;
	}
}

void Gun::DrawBullets(abfw::Renderer3D* render3D)
{
	//-- Itertate through and draw all bullets
	for ( std::vector<Bullet>::iterator mBulletIterator = mCurrentBullets.begin(); mBulletIterator != mCurrentBullets.end(); ++mBulletIterator )
	{
		render3D->SetShader(NULL);
		render3D->DrawMesh(mBulletIterator->GetMeshInstance());
	}
}


void Gun::CleanUpBullets()
{
	//-- Iterate through and clean up bullets
	for (  std::vector<Bullet>::iterator mBulletIterator = mCurrentBullets.begin(); mBulletIterator != mCurrentBullets.end(); ++mBulletIterator )
	{
		delete mBulletIterator->mesh();
	}
}
